package leetcode.calc._06_07;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

/**
 * {{7},{9},{6}}
 */
public class _0714_054_螺旋矩阵_01_my {
    public static void main(String[] args) {

        Solution sol = new _0714_054_螺旋矩阵_01_my().new Solution();
        if (true) {
            int[][] param = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
            String rel = "{1,2,3,6,9,8,7,4,5}";
            List<Integer> res = sol.spiralOrder(param);
            String resStr = "{" + StringUtils.join(res, ",") + "}";
            Assert.isTrue(resStr.equals(rel), String.format("%s!=%s", resStr, rel));
        }
        if (true) {
            int[][] param = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
            String rel = "{1,2,3,4,8,12,11,10,9,5,6,7}";
            List<Integer> res = sol.spiralOrder(param);
            String resStr = "{" + StringUtils.join(res, ",") + "}";
            Assert.isTrue(resStr.equals(rel), String.format("%s!=%s", resStr, rel));
        }
        if (true) {
            int[][] param = {{3}, {2}};
            String rel = "{3,2}";
            List<Integer> res = sol.spiralOrder(param);
            String resStr = "{" + StringUtils.join(res, ",") + "}";
            Assert.isTrue(resStr.equals(rel), String.format("%s!=%s", resStr, rel));
        }
        if (true) {
            int[][] param = {{7}, {9}, {6}};
            String rel = "{7,9,6}";
            List<Integer> res = sol.spiralOrder(param);
            String resStr = "{" + StringUtils.join(res, ",") + "}";
            Assert.isTrue(resStr.equals(rel), String.format("%s!=%s", resStr, rel));
        }
        Vector<Object> ve = new Vector<>();
        Iterator<Object> iterator = ve.iterator();
        Enumeration<Object> elements = ve.elements();
        ArrayList<Object> list = new ArrayList<>();
        Iterator<Object> iterator1 = list.iterator();
        Hashtable<Object, Object> tab = new Hashtable<>();
        Enumeration<Object> elements1 = tab.elements();
        Stack<Object> objects = new Stack<>();
        Object[] ar2 = null;
        Arrays.sort(ar2);
        // 测试 数组的 父类
        String[] arr = {};
        Object[] obs = arr;
        // 测试 List 父类
        List<String> strs = Collections.emptyList();
        List<? extends Object> objs = strs;
        List<? super String> objs2 = strs;
        Object o = objs.get(0);
        objs2.add("31");
        Object s = objs2.get(0);
        // List 比较麻烦
    }

    class Solution {
        public List<Integer> spiralOrder(int[][] arr) {
            int rowCount = 0;
            int rowLen = arr.length;
            int colLen = arr[0].length;

            int startIndex;
            int endIndex;
            int colStartIndex = 0;
            int colEndIndex = colLen;
            List<Integer> res = new ArrayList<>(rowLen * colLen);
            while (rowCount < rowLen && rowCount < colLen) {
                // 遍历行
                startIndex = rowCount / 2;
                endIndex = colLen - ((rowCount + 1) / 2);
                boolean both = (rowCount & 1) == 0;
                if (both) {
                    startRow(startIndex, endIndex, res, arr, colStartIndex);
                } else {
                    endRow(startIndex, endIndex, res, arr, colEndIndex - 1);
                }
                rowCount++;
                // 遍历列
                colStartIndex = (rowCount + 1) / 2;
                colEndIndex = rowLen - (rowCount / 2);
                if (both) {
                    startCol(colStartIndex, colEndIndex, res, arr, endIndex - 1);
                } else {
                    endCol(colStartIndex, colEndIndex, res, arr, startIndex);
                }
            }
            return res;
        }

        private void startRow(int startIndex, int endIndex, List<Integer> res, int[][] arr, int row) {
            for (int i = startIndex; i < endIndex; i++) {
                res.add(arr[row][i]);
            }
        }

        private void endRow(int startIndex, int endIndex, List<Integer> res, int[][] arr, int row) {
            int start = startIndex - 1;
            for (int i = endIndex - 1; i > start; i--) {
                res.add(arr[row][i]);
            }
        }

        private void startCol(int startIndex, int endIndex, List<Integer> res, int[][] arr, int col) {
            for (int i = startIndex; i < endIndex; i++) {
                res.add(arr[i][col]);
            }
        }

        private void endCol(int startIndex, int endIndex, List<Integer> res, int[][] arr, int col) {
            int start = startIndex - 1;
            for (int i = endIndex - 1; i > start; i--) {
                res.add(arr[i][col]);
            }
        }

    }
}